package category

import (
	"context"
	"mall/common/excption"
	constans "mall/services/product/rpc/consts"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/mapper"

	"mall/services/product/rpc/internal/svc"
	"mall/services/product/rpc/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type ManageLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewCategoryManageLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ManageLogic {
	return &ManageLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *ManageLogic) CategoryManage(in *pb.ShopCategoryManageDTO) (*pb.EmptyObj, error) {
	// 1.check request dto
	categoryMapper, checkErr := l.checkRequestDTO(in)
	if checkErr != nil {
		return nil, checkErr
	}
	// 2.save db
	saveErr := categoryMapper.CategoryManage(l.svcCtx.DBEngin, in.CategoryIdArr, in.Status)
	if saveErr != nil {
		return nil, saveErr
	}
	// 3.children to loop
	loopDelErr := l.loopDelChildren(in.CategoryIdArr, categoryMapper, in.Status)
	if loopDelErr != nil {
		return nil, loopDelErr
	}
	// 4.return obj
	return &pb.EmptyObj{}, nil
}

func (l *ManageLogic) loopDelChildren(categoryIdArr []int64, categoryMapper *mapper.CategoryMapper, status int32) error {
	// query category list
	categoryBO := bo.CategoryBO{ParentIdArr: categoryIdArr, NeStatus: constans.Delete}
	selectListCtx, err := categoryMapper.SelectListCtx(l.svcCtx.DBEngin, categoryBO)
	if err != nil {
		return err
	}
	for len(selectListCtx) < 1 {
		return nil
	}
	var childrenIdArr []int64
	for _, v := range selectListCtx {
		childrenIdArr = append(childrenIdArr, v.CategoryId)
	}
	// modify manager
	saveErr := categoryMapper.CategoryManage(l.svcCtx.DBEngin, childrenIdArr, status)
	if saveErr != nil {
		return saveErr
	}
	// next loop
	loopDelErr := l.loopDelChildren(childrenIdArr, categoryMapper, status)
	if loopDelErr != nil {
		return loopDelErr
	}
	return nil
}

func (l *ManageLogic) checkRequestDTO(in *pb.ShopCategoryManageDTO) (*mapper.CategoryMapper, error) {
	categoryMapper := mapper.NewCategoryMapper(l.ctx)
	categoryBO := bo.CategoryBO{
		CategoryIdArr: in.CategoryIdArr,
		NeStatus:      constans.Delete,
	}
	selectCountCtx, err := categoryMapper.SelectCountCtx(l.svcCtx.DBEngin, categoryBO)
	if err != nil {
		return nil, err
	}
	if int(selectCountCtx) == len(in.CategoryIdArr) {
		return nil, excption.NewErrCode(constans.CategoryNotExistErr)
	}
	return categoryMapper, nil
}
